home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 34.zip / BS1 part 34 / Utilities.adf / PPData / ppdata.c next >
C/C++ Source or Header  |  1988-01-20  |  10KB  |  342 lines

  1. /********************************************************************
  2. *                                                                   *
  3. *  PowerPacker DATA file support function V1.1                      *
  4. *  -------------------------------------------                      *
  5. *                            (Read Packer.doc for more information) *
  6. *                                                                   *
  7. *    error = PP_LoadData (file, col, typeofmem, buffer, length, pw) *
  8. *    with:                                                          *
  9. *       char *file;     filename                                    *
  10. *       UBYTE col;      color (see ppdata.h)                        *
  11. *       ULONG typeofmem type of memory that will be allocated       *
  12. *       UBYTE **buffer  pointer to pointer to buffer                *
  13. *       ULONG *length   pointer to buffer length                    *
  14. *       char *pw;       pointer to password or NULL                 *
  15. *                                                                   *
  16. *  NOTE: - After loading you must free the allocated memory:        *
  17. *          DO NOT FORGET !!!!!                                      *
  18. *             FreeMem (buffer, length);                             *
  19. *        - Errors are defined in ppdata.h                           *
  20. *        - For encrypted data call first with pw = NULL, then       *
  21. *          if error is PP_CRYPTED you know file is crypted.         *
  22. *          Prompt the user for a password and call again with       *
  23. *          pw pointing to this password. If the password is         *
  24. *          incorrect error is PP_PASSERR, otherwise the file will   *
  25. *          be loaded and decrypted.                                 *
  26. *                                                                   *
  27. *    Example:                                                       *
  28. *                                                                   *
  29. *      #include <ppdata.h>                                          *
  30. *      ...                                                          *
  31. *                                                                   *
  32. *      UBYTE *mymem = NULL;                                         *
  33. *      ULONG mylen = 0;                                             *
  34. *                                                                   *
  35. *      err = PP_LoadData ("df0:myfile.pp", DECR_POINTER,            *
  36. *                     MEMF_PUBLIC+MEMF_CHIP, &mymem, &mylen, NULL); *
  37. *      if (err == PP_LOADOK) {                                      *
  38. *         DoSomething (mymem, mylen);                               *
  39. *         FreeMem (mymem, mylen);                                   *
  40. *         }                                                         *
  41. *      else switch (err) {                                          *
  42. *         case PP_CRYPTED:                                          *
  43. *            puts ("File is encrypted !");                          *
  44. *            break;                                                 *
  45. *         case PP_READERR:                                          *
  46. *            puts ("Loading error !!!");                            *
  47. *            break;                                                 *
  48. *         ...                                                       *
  49. *         }                                                         *
  50. *                                                                   *
  51. ********************************************************************/
  52. /********************************************************************
  53. *                                                                   *
  54. *  'PP_LoadData' PowerPacker DATA file support function V1.1        *
  55. *                                                                   *
  56. *  You may use this code for non-commercial purposes provided this  *  
  57. *  copyright notice is left intact !                                *
  58. *                                                                   *
  59. *                          Copyright (c) Aug 1989 by Nico François  *
  60. ********************************************************************/
  61.  
  62. #include <exec/types.h>
  63. #include <exec/io.h>
  64. #include <exec/memory.h>
  65. #include <libraries/dos.h>
  66. #include <functions.h>
  67.  
  68. #include <ppdata.h>
  69.  
  70. #define SAFETY_MARGIN    64L
  71. #define SIZEOF                (ULONG)sizeof
  72. #define myRead(to,len)    if (Read (pp_lock, to, len) != len) {\
  73.                                         pp_FreeStuff(); return (PP_READERR); }
  74. struct FileLock *pp_lock;
  75. struct FileInfoBlock *pp_FileInfoBlock;
  76. UBYTE *pp_filestart;
  77. ULONG pp_bufferlen;
  78. UWORD pp_coladdr[4] = { 0xf180, 0xf182, 0xf1a2, 0xf102 };
  79. UWORD pp_CalcCheckSum();
  80. ULONG pp_CalcPasskey();
  81.  
  82. PP_LoadData (pp_file, color, typeofmem, buffer, length, pw)        /* Version 1.1 */
  83. char *pp_file;
  84. UBYTE color;
  85. ULONG typeofmem;
  86. UBYTE **buffer;
  87. ULONG *length;
  88. char *pw;
  89. {
  90.     ULONG hdr, pp_seek;
  91.     UWORD *decrcol, instr, hicol, locol, pp_passchecksum;
  92.     ULONG pp_filelen, pp_crunlen, pp_efficiency;
  93.     UBYTE pp_crunched, pp_crypt = FALSE;
  94.     extern void pp_DecrunchBuffer(), pp_DecrunchColor();
  95.  
  96.     pp_filestart = NULL;
  97.     if (!(pp_FileInfoBlock = (struct FileInfoBlock *)AllocMem
  98.         (SIZEOF(*pp_FileInfoBlock), MEMF_PUBLIC))) return (PP_NOMEMORY);
  99.  
  100.     /* Set decruncher color */
  101.     decrcol = (UWORD *)pp_DecrunchColor;
  102.     if (color != 4) {
  103.         instr = 0x33c9; hicol = 0x00df;
  104.         locol = pp_coladdr[color];                /* = move.w a1,$dff1xx */
  105.         }
  106.     else instr = hicol = locol = 0x4e71;     /* nop */
  107.     *decrcol = instr;
  108.     *(decrcol+1) = hicol; *(decrcol+2) = locol;
  109.  
  110.     if (!(pp_lock = (struct FileLock *)Lock (pp_file, ACCESS_READ))) {
  111.         pp_FreeStuff();
  112.         return (PP_LOCKERR);
  113.         }
  114.     Examine (pp_lock, pp_FileInfoBlock);
  115.     UnLock (pp_lock);
  116.     pp_crunlen = pp_FileInfoBlock->fib_Size;
  117.  
  118.     /* read decrunched length */
  119.     if (!(pp_lock = (struct FileLock *)Open (pp_file, MODE_OLDFILE))) {
  120.         pp_FreeStuff();
  121.         return (PP_OPENERR);
  122.         }
  123.     myRead (&hdr, 4L);
  124.  
  125.     /* check if crunched */
  126.     if ((hdr == 'PX20' || hdr == 'PP11' || hdr == 'PP20') && (pp_crunlen>16L)) {
  127.         if (hdr == 'PX20') {
  128.             if (!pw) {
  129.                 pp_FreeStuff();
  130.                 return (PP_CRYPTED);
  131.                 }
  132.             myRead (&pp_passchecksum, 2L);
  133.             if (pp_CalcCheckSum (pw) != pp_passchecksum) {
  134.                 pp_FreeStuff();
  135.                 return (PP_PASSERR);
  136.                 }
  137.             pp_crypt = TRUE;
  138.             pp_seek = 6L;
  139.             }
  140.         else pp_seek = 4L;
  141.         Seek (pp_lock, pp_crunlen - 4L, OFFSET_BEGINNING);
  142.         myRead (&pp_filelen, 4L);
  143.         pp_filelen >>= 8L;
  144.         pp_crunlen -= 4L + pp_seek;
  145.         Seek (pp_lock, pp_seek, OFFSET_BEGINNING);
  146.         myRead (&pp_efficiency, 4L);
  147.         pp_bufferlen = pp_filelen + SAFETY_MARGIN;
  148.         pp_crunched = TRUE;
  149.         }
  150.     else {
  151.         Seek (pp_lock, 0L, OFFSET_BEGINNING);
  152.         pp_bufferlen = pp_filelen = pp_crunlen;
  153.         pp_crunched = FALSE;
  154.         }
  155.     if (!(pp_filestart=(UBYTE *)AllocMem (pp_bufferlen, typeofmem))) {
  156.         pp_FreeStuff();
  157.         return (PP_NOMEMORY);
  158.         }
  159.     /* load file */
  160.     myRead (pp_filestart, pp_crunlen);
  161.  
  162.     Close (pp_lock);
  163.     FreeMem (pp_FileInfoBlock, SIZEOF(*pp_FileInfoBlock));
  164.     if (pp_crunched) {
  165.         if (pp_crypt)
  166.             pp_Decrypt (pp_filestart, pp_crunlen-4L, pp_CalcPasskey (pw));
  167.         pp_DecrunchBuffer (pp_filestart + pp_crunlen,
  168.                                             pp_filestart + SAFETY_MARGIN, pp_efficiency);
  169.         FreeMem (pp_filestart, SAFETY_MARGIN);
  170.         pp_filestart += SAFETY_MARGIN;
  171.         }
  172.     *buffer = pp_filestart;
  173.     *length = pp_filelen;
  174.     return (PP_LOADOK);
  175. }
  176.  
  177. pp_FreeStuff()
  178. {
  179.     if (pp_lock) Close (pp_lock);
  180.     if (pp_filestart) FreeMem (pp_filestart, pp_bufferlen);
  181.     if (pp_FileInfoBlock) FreeMem (pp_FileInfoBlock, SIZEOF(*pp_FileInfoBlock));
  182. }
  183.  
  184. #asm
  185. ;
  186. ; PowerPacker Decrunch assembler subroutine V1.1
  187. ;
  188. ; call as:
  189. ;    DecrunchBuffer (endcrun, buffer, efficiency);
  190. ; with:
  191. ;    endcrun   : UBYTE * just after last byte of crunched file
  192. ;    buffer    : UBYTE * to memory block to decrunch in
  193. ;    efficiency: Longword defining efficiency with wich file was crunched
  194. ;
  195. ; NOTE:
  196. ;    Decrunch a few bytes higher (safety margin) than the crunched file
  197. ;    to decrunch in the same memory space. (64 bytes suffice)
  198. ;
  199.  
  200.     XDEF _pp_DecrunchBuffer
  201.     XDEF _pp_DecrunchColor
  202.     XDEF _pp_CalcCheckSum
  203.     XDEF _pp_CalcPasskey
  204.     XDEF _pp_Decrypt
  205.  
  206. _pp_DecrunchBuffer:
  207.     move.l 4(a7),a0
  208.     move.l 8(a7),a1
  209.     move.l 12(a7),d0
  210.     movem.l d1-d7/a2-a6,-(a7)
  211.     bsr.s Decrunch
  212.     movem.l (a7)+,d1-d7/a2-a6
  213.     rts
  214. Decrunch:
  215.     lea myBitsTable(PC),a5
  216.     move.l d0,(a5)
  217.     move.l a1,a2
  218.     move.l -(a0),d5
  219.     moveq #0,d1
  220.     move.b d5,d1
  221.     lsr.l #8,d5
  222.     add.l d5,a1
  223.     move.l -(a0),d5
  224.     lsr.l d1,d5
  225.     move.b #32,d7
  226.     sub.b d1,d7
  227. LoopCheckCrunch:
  228.     bsr.s ReadBit
  229.     tst.b d1
  230.     bne.s CrunchedBytes
  231. NormalBytes:
  232.     moveq #0,d2
  233. Read2BitsRow:
  234.     moveq #2,d0
  235.     bsr.s ReadD1
  236.     add.w d1,d2
  237.     cmp.w #3,d1
  238.     beq.s Read2BitsRow
  239. ReadNormalByte:
  240.     move.w #8,d0
  241.     bsr.s ReadD1
  242.     move.b d1,-(a1)
  243.     dbf d2,ReadNormalByte
  244.     cmp.l a1,a2
  245.     bcs.s CrunchedBytes
  246.     rts
  247. CrunchedBytes:
  248.     moveq #2,d0
  249.     bsr.s ReadD1
  250.     moveq #0,d0
  251.     move.b (a5,d1.w),d0
  252.     move.l d0,d4
  253.     move.w d1,d2
  254.     addq.w #1,d2
  255.     cmp.w #4,d2
  256.     bne.s ReadOffset
  257.     bsr.s ReadBit
  258.     move.l d4,d0
  259.     tst.b d1
  260.     bne.s LongBlockOffset
  261.     moveq #7,d0
  262. LongBlockOffset:
  263.     bsr.s ReadD1
  264.     move.w d1,d3
  265. Read3BitsRow:
  266.     moveq #3,d0
  267.     bsr.s ReadD1
  268.     add.w d1,d2
  269.     cmp.w #7,d1
  270.     beq.s Read3BitsRow
  271.     bra.s DecrunchBlock
  272. ReadOffset:
  273.     bsr.s ReadD1
  274.     move.w d1,d3
  275. DecrunchBlock:
  276.     move.b (a1,d3.w),d0
  277.     move.b d0,-(a1)
  278.     dbf d2,DecrunchBlock
  279. EndOfLoop:
  280. _pp_DecrunchColor:
  281.     move.w a1,$dff1a2
  282.     cmp.l a1,a2
  283.     bcs.s LoopCheckCrunch
  284.     rts
  285. ReadBit:
  286.     moveq #1,d0
  287. ReadD1:
  288.     moveq #0,d1
  289.     subq.w #1,d0
  290. ReadBits:
  291.     lsr.l #1,d5
  292.     roxl.l #1,d1
  293.     subq.b #1,d7
  294.     bne.s No32Read
  295.     move.b #32,d7
  296.     move.l -(a0),d5
  297. No32Read:
  298.     dbf d0,ReadBits
  299.     rts
  300. myBitsTable:
  301.     dc.b $09,$0a,$0b,$0b
  302.  
  303. _pp_CalcCheckSum:
  304.     move.l 4(a7),a0
  305.     moveq #0,d0
  306.     moveq #0,d1
  307. sumloop:
  308.     move.b (a0)+,d1
  309.     beq.s exitasm
  310.     ror.w d1,d0
  311.     add.w d1,d0
  312.     bra.s sumloop
  313. _pp_CalcPasskey:
  314.     move.l 4(a7),a0
  315.     moveq #0,d0
  316.     moveq #0,d1
  317. keyloop:
  318.     move.b (a0)+,d1
  319.     beq.s exitasm
  320.     rol.l #1,d0
  321.     add.l d1,d0
  322.     swap d0
  323.     bra.s keyloop
  324. exitasm:
  325.     rts
  326. _pp_Decrypt:
  327.     move.l 4(a7),a0
  328.     move.l 8(a7),d1
  329.     move.l 12(a7),d0
  330.     move.l d2,-(a7)
  331.     addq.l #3,d1
  332.     lsr.l #2,d1
  333.     subq.l #1,d1
  334. encryptloop:
  335.     move.l (a0),d2
  336.     eor.l d0,d2
  337.     move.l d2,(a0)+
  338.     dbf d1,encryptloop
  339.     move.l (a7)+,d2
  340.     rts
  341. #endasm
  342.